-- UISkyCityGroup
-- Create by chendh
-- 天空之城阵营分组界面

-- UISkyCityGroup继承自Layer
UISkyCityGroup = class("UISkyCityGroup", function()
    return cc.Layer:create();
end);

function UISkyCityGroup.create()
    return UISkyCityGroup.new();
end

-- 内部函数声明
local armyCampList = { 2, 1, 3, 4, };
local MAX_GROUP_NUM = #armyCampList;
local itemWidthGap = 320;
local itemheightGap = 80;

-- 构造函数
function UISkyCityGroup:ctor()
    -- 初始化
    self:setName("UISkyCityGroup");
    local node = cc.CSLoader:createNode("layout/sky_city/SkyCityGroup.csb");
    self:addChild(node);
    self.node = node;
    self.selectIndex = table.indexOf(armyCampList, ME.user.dbase:query("activedSkyGroup"));
    self.panel = findChildByName(self.node, "CT/panel");
    self.bottomPanel = findChildByName(self.node, "CT/bottom_panel");

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 注册点击事件
    self:registerTouchEvent();

    -- 初始化
    self:initGrid();

    -- 重绘
    self:redraw();

    self:appearFromCenter();

    -- 适配
    self:resize();
end

-- 适配
function UISkyCityGroup:resize()
    local node = self.node;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");
    AlignM.fitToScreen(node, "bg2");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
    AlignM.alignToBottomCenter(node, "BT2");

    AlignM.alignToTopCenter(node, "Top");

    local CT = findChildByName(self.node, "CT");
    local panelBg = findChildByName(self.node, "CT/bg");
    local CTScale = CT:getScale();
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    panelBg:setScaleX(w / DESIGN_WIDTH / CTScale);
    panelBg:setScaleY(h / DESIGN_HEIGHT / CTScale);
end

-- 重绘界面
function UISkyCityGroup:redraw()
    local campId = armyCampList[self.selectIndex];

    -- 显示标题
    local titleLabel = findChildByName(self.node, "Top/title_bar/title");
    titleLabel:setString(getLocStr("sky_city_group_title"));
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 绘制分组详细信息
    self:redrawDetailInfo();

    -- 绘制容器内的item
    self:redrawGroupItems();
end

-- 绘制分组详细信息
function UISkyCityGroup:redrawDetailInfo()
    local campId        = armyCampList[self.selectIndex];

    local detailNode    = findChildByName(self.node, "BT2/detail_node");
    local groupLabel    = findChildByName(detailNode, "group_name");
    local activedLabel  = findChildByName(detailNode, "actived");
    local fireNode      = findChildByName(detailNode, "fire_node");
    local armorNode     = findChildByName(detailNode, "armor_node");
    local speedNode     = findChildByName(detailNode, "speed_node");
    local luckNode      = findChildByName(detailNode, "luck_node");
    local abilityNode   = findChildByName(detailNode, "ability_node");
    local petNumNode    = findChildByName(detailNode, "pet_num_node");

    -- 阵营名称及是否出战
    TextStyleM.setTextStyle(groupLabel,TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_RED);
    TextStyleM.setTextStyle(activedLabel,TextStyleM.TEXT_SIZE_SMALL2, TextStyleM.TEXT_COLOR_BLUE);

    groupLabel:setString(CampM.query(campId, "name"));
    activedLabel:setString(getLocStr("is_actived"));

    local w = getRealContentSize(groupLabel).width;
    activedLabel:setPositionX(groupLabel:getPositionX() + w);

    if campId == ME.user.dbase:query("activedSkyGroup") then
        activedLabel:setVisible(true);
    else
        activedLabel:setVisible(false);
    end

    -- 绘制四维和总战力，出战冈布奥数量
    local nodeList = { fireNode, armorNode, speedNode, luckNode, abilityNode, petNumNode, };
    local attribStrList = { getLocStr("airship_fire"), getLocStr("airship_armor"), getLocStr("airship_speed"),
                            getLocStr("airship_luck"), getLocStr("total_fight_ability"), getLocStr("slime"), };
    local skyGroup = ME.user.dbase:query("skyArmyGroup", {});
    local petList = skyGroup[armyCampList[self.selectIndex]] or {};
    local robatList = SkyRobotM.getRobotsByCamp(armyCampList[self.selectIndex]);

    local airShipInfo = NewAirShipM.getUserAirShipInfo(NewAirShipM.getActiveAirShip(), petList, robatList, campId);

    -- 计算下出战了多少机器人
    local robatNum = 0;
    for _, num in pairs(robatList) do
        robatNum = robatNum + num;
    end
    local petNumValue = tostring(#petList);

    if robatNum > 0 then
        petNumValue = petNumValue .. "(+" .. tostring(robatNum) .. ")";
    end

    local valueList = { airShipInfo["fire"], airShipInfo["armor"],
                        airShipInfo["speed"], airShipInfo["luck"],
                        SkyCombatM.calcArmyAbility(campId), petNumValue};

    for index, node in ipairs(nodeList) do
        local attribLabel = findChildByName(node, "attrib");
        local valueLabel = findChildByName(node, "value");

        if index >= 5 then
            TextStyleM.setTextStyle(attribLabel, TextStyleM.TEXT_SIZE_MINI, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
        else
            TextStyleM.setTextStyle(attribLabel, TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_BEIGE, false, -1);
        end
        TextStyleM.setTextStyle(valueLabel, TextStyleM.TEXT_SIZE_TINY, TextStyleM.TEXT_COLOR_BEIGE, false, -1);

        attribLabel:setString(attribStrList[index]);
        if type(valueList[index]) == "number" then
            valueLabel:setString(thousandNum(valueList[index]));
        else
            valueLabel:setString(valueList[index]);
        end
    end

    -- 如果是当前出战的飞艇，隐藏出战按钮
    local btnActived = findChildByName(self.node, "BT/btn_actived");
    if campId == ME.user.dbase:query("activedSkyGroup") then
        btnActived:setBright(false);
        btnActived:setTouchEnabled(false);
    else
        btnActived:setBright(true);
        btnActived:setTouchEnabled(true);
    end
end

-- 计算index代表的分组item和指定的分组的距离
function UISkyCityGroup:calcDistance(index, targetIndex)
    local selectIndex = targetIndex or self.selectIndex;

    local fristIndex = index - selectIndex
    local secondIndex = index + MAX_GROUP_NUM - selectIndex;
    local thridIndex = index - MAX_GROUP_NUM - selectIndex;

    local minDistance = math.min(math.abs(fristIndex), math.abs(secondIndex), math.abs(thridIndex));
    if minDistance == math.abs(fristIndex) then
        return fristIndex;
    elseif minDistance == math.abs(secondIndex) then
        return secondIndex;
    elseif minDistance == math.abs(thridIndex) then
        return thridIndex;
    end
end

-- 计算Index代表的分组item在指定的分组为选中分组情况下的坐标
function UISkyCityGroup:calcItemPos(index, targetIndex)
    local selectIndex = targetIndex or self.selectIndex;
    local distance = self:calcDistance(index, selectIndex);
    local origin = { ["x"] = self.panel:getContentSize().width / 2, ["y"] = self.panel:getContentSize().height / 2, };

    return cc.p(origin.x + distance * itemWidthGap, origin.y - 30 + math.abs(distance) * itemheightGap);
end

-- 计算Index代表的分组item在指定的分组为选中分组情况下的比例
function UISkyCityGroup:calcItemScale(index, targetIndex)
    local selectIndex = targetIndex or self.selectIndex;
    local distance = self:calcDistance(index, selectIndex);

    return math.pow(0.8, math.abs(distance));
end

-- 绘制分组item
function UISkyCityGroup:redrawItem(node, index)
    local groupPetList = SkyCombatM.getGroup(armyCampList[index]);
    -- 出战的机器人
    local robotGroup = SkyRobotM.getRobotsByCamp(armyCampList[index]);

    local groupRobotList = {};
    for robotId, num in pairs(robotGroup) do
        for i = 1, num do
            table.insert(groupRobotList, robotId);
        end
    end

    -- 阵营图标
    local campImg = findChildByName(node, "camp");
    campImg:loadTexture(getSkyCityGroupCampPath(armyCampList[index]));

    -- 绘制分组上面的5个冈布奥
    for i = 1, 5 do
        local petNode = findChildByName(node, "pet" .. i);
        if #groupPetList + #groupRobotList >= i then
            petNode:setVisible(true);

            if #groupPetList >= i then
				local pet = PetM.getMyPet(groupPetList[i]);
                local iconIndex = pet:getIcon();
                petNode:loadTexture(getHeroIconPath(iconIndex));
                petNode:setScale(0.8);
            else
                local iconIndex = SkyRobotM.query(groupRobotList[i - #groupPetList], "icon");
                petNode:loadTexture(getRobotIconPath(iconIndex));
            end
        else
            petNode:setVisible(false);
        end
    end
end

-- 绘制容器内的item
function UISkyCityGroup:redrawGroupItems(needRedraw)
    for i = 1, MAX_GROUP_NUM do
        local child = findChildByName(self.bottomPanel, "item" .. i);
        local bgEffect = findChildByName(child, "bg_effect");

        child:setPosition(self:calcItemPos(i));
        child:setScale(self:calcItemScale(i));

        -- 绘制下内容
        if needRedraw or not child.hasInit then
            self:redrawItem(child, i);
            child.hasInit = true;

            bgEffect:removeAllChildren();
            playEffect(bgEffect, 1816);
        end

        -- 当前选中的分组不显示，其他的全部显示

        if i == self.selectIndex then
            child:setVisible(false);
        else
            child:setVisible(true);
        end
    end

    -- 绘制panel中选中的分组
    local child = findChildByName(self.panel, "selectItem");
    child:setPosition(self:calcItemPos(self.selectIndex));
    child:setScale(self:calcItemScale(self.selectIndex));

    -- 绘制下内容
    self:redrawItem(child, self.selectIndex);

    -- 选中的分组要轻微悬浮
    if not child.init then
        local bgEffect = findChildByName(child, "bg_effect");
        bgEffect:removeAllChildren();
        playEffect(bgEffect, 1815);

        -- 选中的分组要轻微悬浮
        playFluctuateAnima(child, 1, 5);
        child.init = true;
    end
end

-- 初始化分组节点
function UISkyCityGroup:initGrid()
    local itemNode = cc.CSLoader:createNode("layout/sky_city/SkyCityGroupItem.csb");
    local widget = replaceNodeWithWidget(itemNode);

    for i = 1, MAX_GROUP_NUM do
        local child = widget:clone();
        child:setTag(i);
        child:setName("item" .. i);
        self.bottomPanel:addChild(child);
    end

    local child = widget:clone();
    child:setName("selectItem");
    self.panel:addChild(child);
end

-- 移动
function UISkyCityGroup:moveItems(direction, callback)
    local delay = 0.2;

    for i = 1, MAX_GROUP_NUM do
        local child;
        if i == self.selectIndex then
            child = findChildByName(self.panel, "selectItem");
        else
            child = findChildByName(self.bottomPanel, "item" .. i);
        end

        -- 计算这次移动后，选中的item会变成哪一个
        local nextIndex;
        if direction == 1 then
            nextIndex = self.selectIndex + 1;
            if nextIndex > MAX_GROUP_NUM then
                nextIndex = 1;
            end
        elseif direction == -1 then
            nextIndex = self.selectIndex - 1;
            if nextIndex <= 0 then
                nextIndex = MAX_GROUP_NUM;
            end
        end

        -- 计算child要移动到哪个位置，比例又是多少
        local curPos = self:calcItemPos(i);
        local desPos = self:calcItemPos(i, nextIndex);
        local movePos = cc.p(direction * -1 * itemWidthGap, desPos.y - curPos.y);

        -- 只有当分组只有4组的时候需要这个特殊处理
        -- 当只有4个分组的情况下无法满足往任意一方移动均可保证另一方向有个分组可以移动进来
        if MAX_GROUP_NUM == 4 then
            if direction == 1 then
                if i == self.selectIndex - 2 or i == self.selectIndex + 2 then
                    child:setPositionX(desPos.x + itemWidthGap);
                end
            else
                if i == self.selectIndex - 2 or i == self.selectIndex + 2 then
                    child:setPositionX(desPos.x - itemWidthGap);
                end
            end
        end

        local moveBy = cc.MoveBy:create(delay, movePos);
        local scaleTo = cc.ScaleTo:create(delay, self:calcItemScale(i, nextIndex));
        local callFunc = cc.CallFunc:create(function()
            child:setVisible(true);
        end);
        child:runAction(cc.Sequence:create(callFunc, cc.Spawn:create(moveBy, scaleTo)));
    end

    performWithDelay(self, callback, delay);
end

-- 注册事件处理回调函数
function UISkyCityGroup:registerEventCallback()
    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            EventMgr.removeAll("UISkyCityGroup");
            local uiForm = UIMgr.getCurrentScene():getFormByName("UISkyCity");
            if uiForm then
                uiForm:tryPlaySkyTowerApearEffect();
            end
        elseif eventType == "enter" then

        end
    end);

    -- 注册获得焦点的回调
    EventMgr.register("UISkyCityGroup", event.FOCUS_CHANGED, function(para)
        if para["get"] == "UISkyCityGroup" then
            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(true);

            UIMgr:getCurrentScene().topMenu:show(TOPMENU_FRAME_AIRSHIP_SCORE, TOPMENU_FRAME_AIRSHIP_ATTRIB, TOPMENU_FRAME_HEAD_AIRSHIP);
        elseif para["lose"] == "UISkyCityGroup" then
            local btNode = findChildByName(self.node, "BT");
            btNode:setVisible(false);
        end
    end);

    -- 编组发生变化的回调
    EventMgr.register("UISkyCityGroup", event.SKY_CITY_SAVE_GROUP, function(para)
        self:redrawGroupItems(true);
        self:redrawDetailInfo();
    end);

    -- 设置出战的编组发生变化的回调
    EventMgr.register("UISkyCityGroup", event.SKY_ACTIVE_GROUP, function(para)
        self:redrawDetailInfo();

        -- 播放出战特效
        self:playGroupActivedEffect();
    end);
end

-- 注册点击事件
function UISkyCityGroup:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            -- 关闭当前界面
            AudioM.playFx("ship_return");
            UIMgr.getCurrentScene():removeFormByName("UISkyCityGroup");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册出战按钮点击事件
    local btnActived = findChildByName(self.node, "BT/btn_actived");
    local function onActivedClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            local campId = armyCampList[self.selectIndex];
            local petList = SkyCombatM.getGroup(campId);
            local robotMap = SkyRobotM.getRobotsByCamp(campId);

            local robotNum = 0;
            for _, num in pairs(robotMap) do
                robotNum = robotNum + num;
            end

            if robotNum <= 0 and #petList <= 0 then
                alert(getLocStr("not_pet_actived"));
                return;
            end

            -- 出战
            SkyCombatM.activeGroup(campId);

            AudioM.playFx("camp_play");
        end
    end
    btnActived:addTouchEventListener(onActivedClick);
    TextStyleM.setTextStyle(btnActived, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnActived:setTitleText(getLocStr("btn_text_actived"));

    -- 注册编组按钮点击事件
    local btnTeam = findChildByName(self.node, "BT/btn_team");
    local function onTeamClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("ship_click");
            -- 打开编组界面
            require "game/ui/form/sky_city/UISkyCityTeam"
            local UISkyCityTeam = UISkyCityTeam.create(armyCampList[self.selectIndex]);
            UIMgr.getCurrentScene():addForm(UISkyCityTeam);
        end
    end
    btnTeam:addTouchEventListener(onTeamClick);
    TextStyleM.setTextStyle(btnTeam, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnTeam:setTitleText(getLocStr("btn_text_group"));

    -- panel点击处理
    local function onPanelClick(sender,eventType)
        if self.isMoveing then
            return;
        end

        if eventType == ccui.TouchEventType.ended then
            sender.initMoveX = nil;
        elseif eventType == ccui.TouchEventType.began then
            sender.initMoveX = nil;
        elseif eventType == ccui.TouchEventType.moved then
            local movePos = sender:getTouchMovePosition();
            if not sender.initMoveX then
                sender.initMoveX = movePos.x;
            end

            local direction;
            local moveLen = AlignM.frameSize.width / 10;
            if movePos.x - sender.initMoveX > moveLen then
                -- 往右滑动
                direction = -1;
            elseif movePos.x - sender.initMoveX < -1 * moveLen then
                -- 往左滑动
                direction = 1;
            else
                return;
            end

            -- 先停止点击事件的回调
            self.isMoveing = true;
            sender.initMoveX = movePos.x;

            local function callback()
                self.isMoveing = false;
                if direction == 1 then
                    self.selectIndex = self.selectIndex + 1;
                    if self.selectIndex > MAX_GROUP_NUM then
                        self.selectIndex = 1;
                    end
                elseif direction == -1 then
                    self.selectIndex = self.selectIndex - 1;
                    if self.selectIndex <= 0 then
                        self.selectIndex = MAX_GROUP_NUM;
                    end
                end

                -- 重绘下
                self:redraw();
            end

            -- 移动
            self:moveItems(direction, callback);
            AudioM.playFx("camp_select");
        end
    end

    self.panel:addTouchEventListener(onPanelClick);
end

-- 获取选中的分组阵营
function UISkyCityGroup:getSelectGroup()
    return armyCampList[self.selectIndex];
end

-- 播放出战特效
function UISkyCityGroup:playGroupActivedEffect()
    -- 先在panel中创建一个item节点
    local panel = self.panel;
    local activedGroup = ME.user.dbase:query("activedSkyGroup");
    local node = cc.CSLoader:createNode("layout/sky_city/SkyCityGroupItem.csb");

    -- 提示语
    -- "出战！%s!"
    alert(string.format(getLocStr("activate_group_tip"), CampM.query(activedGroup, "name")));

    -- 调用redrawItem接口绘制下item节点中的冈布奥或者机器人
    self:redrawItem(node, self.selectIndex);
    node:setPosition(self:calcItemPos(self.selectIndex));
    panel:addChild(node);

    local campImg = findChildByName(node, "camp");
    campImg:setVisible(false);

    -- 播放放大并且淡出的特效
    local delay     = 0.5;
    local effectGroup = { {1, 3, 5}, {2, 4} };

    for index, group in ipairs(effectGroup) do
        for _, i in ipairs(group) do
            local petNode = findChildByName(node, "pet" .. i);

            if petNode:isVisible() then
                local delayTime = cc.DelayTime:create((index - 1) * 0.2);
                local scaleTo   = cc.ScaleTo:create(delay, 1.5);
                local fadeOut   = cc.FadeOut:create(delay);
                local callFunc  = cc.CallFunc:create(function ()
                    petNode:setVisible(true);
                end)
                petNode:setVisible(false);

                petNode:runAction(cc.Sequence:create(delayTime, callFunc, cc.Spawn:create(scaleTo, fadeOut)));
            end
        end
    end

    performWithDelay(node, function ()
        node:removeFromParent();
    end, 1 + delay);
end

-- 从中间弹出
function UISkyCityGroup:appearFromCenter()
    local top = findChildByName(self.node, "Top");

    local bt2 = findChildByName(self.node, "BT2");

    local titleNode = findChildByName(top, "title_bar");
    local descNode = findChildByName(bt2, "detail_node");

    local oldScale = titleNode:getScale();
    local descSale = descNode:getScale();

    -- title
    titleNode:setScale(oldScale * 0.8);
    local scaleUp1 = cc.EaseIn:create(cc.ScaleTo:create(0.2, oldScale * 1.05), 0.4);
    local scaleUp2 = cc.ScaleTo:create(0.05, oldScale);
    titleNode:runAction(cc.Sequence:create(scaleUp1, scaleUp2));

    descNode:setScale(descSale * 0.8);
    local scaleUp3 = cc.EaseIn:create(cc.ScaleTo:create(0.2, descSale * 1.05), 0.4);
    local scaleUp4 = cc.ScaleTo:create(0.05, descSale);
    descNode:runAction(cc.Sequence:create(scaleUp3, scaleUp4));
end
